/****** MP3.c *****************************************************
 *
 * Tyler Fultz
 * 1/15/13
 *
 **********************************************************************/
#include "MP3.h"

void MP3Init() {

    /* Configure Inputs and Outputs for Chip Select and Data Requisition    */
    MP3_CS_DIR      = 0;                /* Configure MP3_CS as output       */
    MP3_CS          = 1;                /* Deselect MP3_CS                  */
    MP3_RST_DIR     = 0;                /* Configure MP3_RST as output      */
    MP3_RST         = 1;                /* Set MP3_RST pin                  */

    DREQ_DIR        = 1;                /* Configure DREQ as input          */
    BSYNC_DIR       = 0;                /* Configure BSYNC as output        */
    BSYNC           = 0;            	/* Clear BSYNC                      */
    BSYNC           = 1;           	/* Clear BSYNC                      */

    //MP3 RESET START
    MP3_RST = 0; //Drive low to foce VS hardware reset
    Delay(200); // Need a delay of at least 1.8 ms using standard 12.288 Mhz clock
    MP3_CS = 1; //Deselect Control
    BSYNC = 1; //Deselect Data
    MP3_RST = 1; // Drive back high to break out of reset

    SCI_Spi2Write(SCI_VOL_ADDR, 0xFFFF); //Declick
    SCI_Spi2Write(SCI_AUDDATA_ADDR, 0x000A); //8kHz to auddata
    Delay(10000);

    SCI_Spi2Write(SCI_VOL_ADDR, 0xFEFE); //Switch on analog
    SCI_Spi2Write(SCI_AUDDATA_ADDR, 0x1F40); //8kHz to auddata

    SCI_Spi2Write(SCI_VOL_ADDR, 0x0A0A); //Initial volume set

    MP3SoftReset(); //soft reset, prepare for data

    //Speed up SPI clock
    SPI2_Clock_Speed(0,1);  /* Set up for 8 MHz clock */

    //MP3 READY

    SCI_Spi2Write(SCI_MODE_ADDR, 0x0800); //normal
    SCI_Spi2Write(SCI_BASS_ADDR, 0x7A00);
    SCI_Spi2Write(SCI_CLOCKF_ADDR, 0x8800); // default 12 288 000 Hz
    SCI_Spi2Write(SCI_AUDDATA_ADDR, 0xAC80); //44100 Hz to auddata sample rate
    SCI_Spi2Write(SCI_VOL_ADDR, 0xFEFE); //start with lowest volume


}

void MP3SoftReset() {

    SCI_Spi2Write(SCI_MODE_ADDR, 0x0804);
    Delay(100);
    while (DREQ == 0); //wait for start up

    SCI_Spi2Write(SCI_CLOCKF_ADDR, 0xB3FE);
    Delay(100);
    while (DREQ == 0); //wait for DREQ

}

/*************************************************************************************
 *
 * This function is used to send Serial commands to peripheral devices
 *
 *************************************************************************************/
void SCI_Spi2Write(uint8 ADDR, uint16 DataIn) {
    BSYNC = 1; /* Bit Sync    */
    MP3_CS = chip_select; /* Chip Select */

    SPI2_Write(WRITE_CODE); /* Send Command - Write */
    SPI2_Write(ADDR); /* Send Address - ADDR  */
    SPI2_Write(hi(DataIn)); /* Send 15:8 Data       */
    SPI2_Write(lo(DataIn)); /* Send MSB 7:0 Data    */

    MP3_CS = chip_deselect; /* Let go of chip */
    while (DREQ == 0); /* Wait for data requisition bit */
}

/**********************************************************************************
 *
 * This function was intended to be used to read data from an SD card or the onboard
 * flash memory.  However, this code was not tested or used in this project.
 *
 **********************************************************************************/
void SCI_Spi2Read(uint8 start_address, uint8 num_words, uint16 *data_buffer) {
    uint16 temp;

    BSYNC = 1; /* Sync Chip*/
    MP3_CS = chip_select; /* Select Chip*/
    SPI2_Write(READ_CODE); /* Send Ready Code*/
    SPI2_Write(start_address); /* Send Start Address */

    while (num_words--) {
        temp = SPI2_Write(0xFF); /* Read from SPI2 Buffer*/
        temp <<= 8; /* MSB comes first, shift up */
        temp += SPI2_Write(0xFF); /* Shift in LSB - 7:0 */
        *(data_buffer++) = temp; /* Store in array */
    }

    MP3_CS = chip_deselect; /* Deselect Chip */

}

/***********************************************************
 *
 *  This function sends data over the SPI bus as uninterrupted
 *  serial data
 *
 ***********************************************************/
void SDI_Spi2Write(uint8 *data, uint16 num_bytes, uint8 zerowrite) //SDI num_bytes write
{
    int i;

    MP3_CS = 1; /* Chip Select*/
    BSYNC = 0;  /* Bit Sync */

    while (DREQ == 0); /* Wait for dreq */

    if (!zerowrite) {
        for (i = 0; i < num_bytes; ++i) {
            SPI2_Write(data[i]);
        }
    } else {
        for (i = 0; i < num_bytes; ++i) {
            SPI2_Write(0x00);
        }
    }

    BSYNC = 1;
}


